//@author A0101728M

/*
Hold one date/time information.
Uses Boost date_time library
Throws exceptions (by Boost) derived from std::out_of_range to indicate which aspect of the date inputs are invalid.
*/

#ifndef _DATE_h_
#define _DATE_h_

#ifndef Q_MOC_RUN
#include "boost/date_time/gregorian/gregorian.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#endif
#include <cstring>
#include <iostream>

//const char* DAYS_OF_WEEK[] = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};

class Date{
private:
	boost::posix_time::ptime timeinfo;
	void updateTime(boost::posix_time::time_duration newTime);
	void updateDate(boost::gregorian::date newDate);

public:
	//constructors
	Date(); //ptime of 0, equivalent to date Jan 1, 1970
	Date(int year, int month, int date, int hour, int minute);
	Date(boost::posix_time::ptime time);

	//Misc:
	static Date now(); //return current system time as a new Date.

	//Set to this date object:
	void set(boost::posix_time::ptime time);
	void setMinute(int inputMinute);
	void setHour(int inputHour);
	void setDate(int inputDate);
	void setMonth(int inputMonth);
	void setYear(int inputYear);
	boost::posix_time::ptime setAllFields(int year, int month, int d, int h, int minutes);

	//Get from this date object:
	boost::posix_time::ptime get() const; //const for use in operators
	int getMonth();//0-11
	int getYear();//YYYY
	int getDate();//1-31
	int getDay();//Mon/Tue/...
	int getHour();//0-23
	int getMinute();//0-59

	//Manipulate value of this date object:
	Date addHours(int inputHours);
	Date addMinutes(int inputMinutes);
	Date addDays(int inputDays);
	Date addWeeks(int inputWeeks);
	Date addYears(int inputYears);

	//Returns date/time as a displayable string
	std::string toString();
	std::string toDisplayString(); //for displaying to window
	std::string toStringIncSec();
	
	//Parses a given date/time string and sets the current object to it.
	void fromString(std::string s);

	//Check if date is vaild
	bool isValid();

	//Operators
	bool Date::operator > (const Date& rhs);
	bool Date::operator >= (const Date& rhs);
	bool Date::operator < (const Date& rhs);
	bool Date::operator <= (const Date& rhs);
	bool Date::operator == (const Date& rhs);
	bool Date::operator != (const Date& rhs);
	bool Date::operator = (const Date& rhs);

	// Auxillary
	int checkMonthLetter(std::string st);
	int parseInt(std::string st);
	std::string parseDate(std::string st);
	std::string parseTime(std::string st);
	int parseMonth(std::string st);
	int parseDayInWeek(std::string st);
	std::string appendZero(int i);
	bool isLeapYear(int y);
};
#endif